<template>
  <div>
    <el-card class="box-card">
      <el-form label-width="70px">
        <el-form-item label="SPU名称">
          <el-input placeholder="请输入SPU名称" v-model.trim="spuItem.spuName" />
        </el-form-item>
        <el-form-item label="品牌">
          <el-select placeholder="请选择" v-model="spuItem.tmId">
            <el-option
              v-for="item in trademarkList"
              :key="item.id"
              :label="item.tmName"
              :value="item.tmName"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="SPU描述">
          <el-input type="textarea" placeholder="SPU描述" v-model.trim="spuItem.description" />
        </el-form-item>
        <el-form-item label="SPU图片">
          <el-upload
            v-model:file-list="fileList"
            :action="action"
            list-type="picture-card"
            :on-preview="handlePictureCardPreview"
            :on-remove="handleRemove"
            :on-success="handleAvatarSuccess"
            :before-upload="beforeAvatarUpload"
          >
            <el-icon>
              <Plus />
            </el-icon>
          </el-upload>
        </el-form-item>
        <el-form-item label="销售属性">
          <el-select :placeholder="`还有${noSelectSaleValueList.length}未选择`" v-model="spuId">
            <el-option
              v-for="item in noSelectSaleValueList"
              :key="item.id"
              :label="item.name"
              :value="item.id"
            />
          </el-select>
          <el-button class="my-btn" type="primary" @click="addSaleAttr" :disabled="!spuId"
            >添加销售属性
          </el-button>
          <el-table border style="width: 100%" :data="spuItem.spuSaleAttrList">
            <el-table-column type="index" label="序号" width="100" />
            <el-table-column prop="saleAttrName" label="属性名" width="180" />
            <el-table-column label="属性值名称列表">
              <template #default="{ row }">
                <el-tag
                  v-for="(tag, index) in row.spuSaleAttrValueList"
                  :key="tag.id"
                  class="mx-1"
                  closable
                  @close="row.spuSaleAttrValueList.splice(index, 1)"
                >
                  {{ tag.saleAttrValueName }}
                </el-tag>
                <el-input
                  v-if="row.isInput"
                  ref="InputRef"
                  v-model.trim="row.newAttrValueName"
                  class="ml-1 w-20 tag-input"
                  size="small"
                  @keyup.enter="row.isInput = false"
                  @blur="toButton(row)"
                />
                <el-button v-else class="button-new-tag ml-1" size="small" @click="toInput(row)">
                  + New Tag
                </el-button>
              </template>
            </el-table-column>
            <el-table-column label="操作">
              <template #default="{ $index }">
                <!--suppress TypeScriptValidateTypes -->
                <el-button
                  type="danger"
                  size="small"
                  :icon="Delete"
                  @click="spuItem.spuSaleAttrList.splice($index, 1)"
                />
              </template>
            </el-table-column>
          </el-table>
          <div class="btn">
            <el-button type="primary" @click="reqSave" :disabled="!spuItem.spuSaleAttrList.length"
              >保存
            </el-button>
            <el-button class="my-btn" @click="cancel">取消</el-button>
          </div>
        </el-form-item>
      </el-form>
    </el-card>
  </div>
</template>

<script setup lang="ts">
import { computed, nextTick, onMounted, ref } from 'vue'
import { Delete, Plus } from '@element-plus/icons-vue'
import type { UploadProps } from 'element-plus'
import {
  reqAddSpu,
  reqAllSaleAttrValue,
  reqEditSpu,
  reqSpuDetail,
  reqSpuImageList
} from '@/api/spu'
import type {
  ISpuListItem,
  SpuSaleAttrItem,
  TrademarkItem,
  BaseSaleAttrValueName
} from '@/api/types'
import { reqAllTrademark } from '@/api/trademark'
import { useCategoryStore } from '@/stores/category'
import { storeToRefs } from 'pinia'
import { ElMessage } from 'element-plus'

const action = import.meta.env.VITE_API_URL + '/admin/product/upload'
const categoryStore = useCategoryStore()
const { category3Id } = storeToRefs(categoryStore)
const InputRef = ref()
const props = defineProps<{
  showId?: number | string
}>()
const emit = defineEmits<{
  (e: 'showForm', state: number): void
}>()
const spuId = ref<number | string>('')

const spuItem = ref<ISpuListItem>({
  category3Id: category3Id.value as number,
  description: '',
  spuImageList: [],
  spuName: '',
  spuSaleAttrList: [],
  tmId: 0
})
const trademarkList = ref<TrademarkItem[]>([])
const baseSaleValueList = ref<BaseSaleAttrValueName[]>([])
const fileList = computed(() => {
  return spuItem.value.spuImageList.map((item) => {
    return {
      name: item.imgName,
      url: item.imgUrl
    }
  })
})
const noSelectSaleValueList = computed(() => {
  return baseSaleValueList.value.filter((item1) => {
    return !spuItem.value.spuSaleAttrList.some((item2) => item1.id === item2.baseSaleAttrId)
  })
})

const reqSave = async () => {
  const res = props.showId ? await reqEditSpu(spuItem.value) : await reqAddSpu(spuItem.value)
  if (res.code === 200) {
    ElMessage.success(props.showId ? '编辑成功！' : '添加成功！')
    emit('showForm', 1)
  }
}

const cancel = () => {
  emit('showForm', 1)
}

const addSaleAttr = () => {
  const attr = baseSaleValueList.value.find((item) => item.id === spuId.value)
  if (attr) {
    spuItem.value.spuSaleAttrList.push({
      baseSaleAttrId: attr.id,
      saleAttrName: attr.name,
      spuSaleAttrValueList: [],
      isInput: true
    })
    spuId.value = ''
    nextTick(() => {
      InputRef.value?.focus()
    })
  }
}

const toButton = (row: SpuSaleAttrItem) => {
  row.isInput = false
  const isRepeat = row.spuSaleAttrValueList.some(
    (item) => item.saleAttrValueName === row.newAttrValueName
  )
  if (!row.newAttrValueName || isRepeat) {
    ElMessage.error(isRepeat ? '属性值不能重复！' : '属性值不能为空')
    row.newAttrValueName = ''
  } else {
    row.spuSaleAttrValueList.push({
      saleAttrValueName: row.newAttrValueName,
      baseSaleAttrId: row.baseSaleAttrId
    })
    row.newAttrValueName = ''
  }
}
const toInput = (row: SpuSaleAttrItem) => {
  row.isInput = true
  nextTick(() => {
    InputRef.value?.focus()
  })
}

const getEditData = async () => {
  if (props.showId) {
    const [detail, imgList] = await Promise.all([
      reqSpuDetail(props.showId as number),
      reqSpuImageList(props.showId as number)
    ])
    if (detail.code === 200 && imgList.code === 200) {
      spuItem.value = detail.data
      spuItem.value.spuImageList = imgList.data
    } else {
      spuItem.value = {
        category3Id: 0,
        description: '',
        spuImageList: [],
        spuName: '',
        spuSaleAttrList: [],
        tmId: 0
      }
    }
  }
}

const getPublicData = async () => {
  const [trademark, baseSaleValue] = await Promise.all([reqAllTrademark(), reqAllSaleAttrValue()])
  if (trademark.code === 200 && baseSaleValue.code === 200) {
    trademarkList.value = trademark.data
    baseSaleValueList.value = baseSaleValue.data
  } else {
    trademarkList.value = []
    baseSaleValueList.value = []
  }
}

onMounted(() => {
  getEditData()
  getPublicData()
})

const dialogImageUrl = ref('')
const dialogVisible = ref(false)

const handleRemove: UploadProps['onRemove'] = (uploadFile, uploadFiles) => {
  console.log(uploadFile, uploadFiles)
}
const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile) => {
  dialogImageUrl.value = uploadFile.url!
  dialogVisible.value = true
}

const handleAvatarSuccess: UploadProps['onSuccess'] = (response, uploadFile) => {
  spuItem.value.spuImageList.push({
    imgUrl: response.data,
    imgName: uploadFile.name
  })
}

const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {
  if (rawFile.type !== 'image/jpeg') {
    ElMessage.error('Avatar picture must be JPG format!')
    return false
  } else if (rawFile.size / 1024 / 1024 > 2) {
    ElMessage.error('Avatar picture size can not exceed 2MB!')
    return false
  }
  return true
}
</script>
<script lang="ts">
export default {
  name: 'SpuForm'
}
</script>

<style scoped lang="scss">
.el-card,
.el-table,
.btn {
  margin-top: 16px;
}

.tag-input {
  width: 80px;
}

.my-btn {
  margin-left: 10px;
}
</style>
